Analisi degli streaming su Spotify nel 2024¶
Perchè ho deciso di svolgere il progetto su questo argomento?¶
• l'interesse per la musica
• il desiderio di capire quali sono i trend musicali negli altri paesi
• un'analisi di questo tipo può essere utile per marketing e sponsorizzazione
Quali domande mi sono posta?¶
- Quali sono gli artisti che hanno il maggior numero di streaming?
- Quali sono i paesi che hanno un maggior/minor numero di streaming?
- Come varia la distribuzione del numero di stream nei vari paesi?
- Qual è l'artista più ascoltato in ogni paese?
Descrizione del Dataset¶
fonte: Kaggle
contenuto: trend di streaming su Spotify nel 2024 in 20 diversi paesi del mondo
ad esempio: paesi, artisti, genere, numero di stream (totali, media mensile, ultimi 30 giorni), ...
Analisi dei dati¶
import pandas as pd
import matplotlib as mpl
import numpy as np
import seaborn as sb
import matplotlib.pyplot as plt
import plotly.express as px # per le mappe coropletiche
df = pd.read_csv('Desktop/moststream.csv') # importo il dataset
df.to_csv('dataset_completo4.csv', index=False)
1. Quali sono gli artisti che hanno il maggior numero di streaming?¶
# calcolo il numero di stream totale per ogni artista e li ordino in modo decrescente
top_artists = df.groupby('Artist')['Total Streams (Millions)'].sum().sort_values(ascending=False)
# imposto la grandezza del grafico
plt.figure(figsize=(12, 6))
# creo il grafico
grafico = sb.barplot(x=top_artists.values, y=top_artists.index, hue=top_artists.index, palette='rocket')
# etichetto gli assi
plt.title('Most Streamed Artists (Millions)')
plt.xlabel('Total Streams (Millions)')
plt.ylabel('Artist')
# aggiungo i valori accanto a ogni barra
for i, l in enumerate(top_artists.values): # i=posizione della barra nel grafico, l=lunghezza barra
grafico.text(l + 1, i, str(l), va='center')
plt.show()
2. Quali sono i paesi che hanno un maggior/minor numero di streaming?¶
# calcolo top e worst 5 paesi
top_countries = df.groupby('Country')['Total Streams (Millions)'].sum().sort_values(ascending=False).head(5)
worst_countries = df.groupby('Country')['Total Streams (Millions)'].sum().sort_values(ascending=False).tail(5)
# converto in DataFrame, resetto l'indice attuale e metto come indice numeri incrementali partendo da 0
top_df = top_countries.reset_index()
worst_df = worst_countries.reset_index()
# aggiungo una riga vuota per separare i top dai worst
separator = pd.DataFrame({'Country': [''], 'Total Streams (Millions)': [0]})
# combino assieme i due
combined_df = pd.concat([top_df, separator, worst_df])
# imposto grandezza del grafico
plt.figure(figsize=(12, 9))
# creo il grafico
grafico = sb.barplot(data=combined_df, x='Total Streams (Millions)', y='Country', hue = 'Country', palette='mako')
# etichetto gli assi
plt.title('Top and Worst 5 Countries by Total Streams (Millions)')
plt.xlabel('Total Streams (Millions)')
plt.ylabel('Country')
# aggiungo i valori accanto a ogni barra
for i, l in enumerate(combined_df['Total Streams (Millions)']):
if combined_df['Country'].iloc[i] != '': # salto la riga vuota
grafico.text(l + 1, i, str(l), va='center')
plt.show()
import plotly.io as pxio
pxio.renderers.default = 'iframe_connected'
# calcolo il totale di stream per ogni paese
selezione_col_million_stream = df.groupby('Country')['Total Streams (Millions)'].sum().reset_index()
# creo una mappa coropletica
fig = px.choropleth(
selezione_col_million_stream,
locations = 'Country', # nomi dei paesi per trovare la posizione sulla mappa
locationmode = 'country names', # specifico il tipo di dato (nomi completi dei paesi)
color = 'Total Streams (Millions)', # valore da mappare
color_continuous_scale = 'Viridis', # palette per dati non categorici (valori non discreti ma continui)
title = 'Total Streams by Country' # etichetta/titolo del grafico
)
fig.show(renderer='notebook')
3. Come varia la distribuzione del numero di stream nei vari paesi?¶
# imposto la grandezza del grafico
fig, ax = plt.subplots(figsize = (8, 4))
# creo il boxplot
sb.boxplot(df, y = 'Total Streams (Millions)', x='Country', hue = 'Country', palette = 'hls' );
# ruoto le etichette
plt.xticks(rotation=90)
plt.show()
4. Qual è l'artista più ascoltato in ogni paese?¶
# raggruppo i dati per paese e artista sommando gli stream di ogni artista per ogni paese
selezione_col_paese_artista = df.groupby(['Country', 'Artist'])['Total Streams (Millions)'].sum().unstack(fill_value=0)
#fill_value=0 per mettere 0 su valori NaN eventuali
# seleziono da dove prendere i dati che mi interessano
paesi = selezione_col_paese_artista.index
artisti = selezione_col_paese_artista.columns
valori = selezione_col_paese_artista.values
# grandezza delle barre
x = np.arange(len(paesi)) # array con posizione per ogni paese sull'asse x
larghezza = 0.8 / len(artisti) # larghezza delle barre, divisione spazio per non sovrapporle
# creo il grafico
fig, ax = plt.subplots(figsize=(10, 6))
# creo la palette
palette = [
'#e6194b', # rosso
'#3cb44b', # verde
'#ffe119', # giallo
'#0082c8', # blu
'#f58231', # arancione
'#911eb4', # viola
'#46f0f0', # azzurro
'#f032e6', # magenta
'#d2f53c', # lime
'#fabebe', # rosa chiaro
'#008080', # verde petrolio
'#e6beff', # lilla
'#aa6e28', # marrone
'#800000', # bordeaux
'#aaffc3' # verde menta
]
# assegno a ogni artista un colore della palette
for i, artista in enumerate(artisti): # enumerate(artisti): per ottenere indice e nome dell'artista
ax.bar(
x + i * larghezza, # posizione delle barre
valori[:, i], # altezza delle barre
width=larghezza, # larghezza delle barre
label=artista, # do l'etichetta
color=palette[i] # asssegno colore dalla palette
)
# etichetto gli assi
ax.set_xlabel('Paesi')
ax.set_ylabel('Total Stream (Millions)')
# do il titolo
ax.set_title('Stream totali per artista e paese')
# centro le etichette rispetto alle barre
ax.set_xticks(x + larghezza * (len(artisti) - 1) / 2)
# ruoto le etichette
ax.set_xticklabels(paesi, rotation=90)
# porto la legenda fuori dal grafico per non coprire le barre
ax.legend(title='Artisti', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()
import plotly.io as pxio
pxio.renderers.default = 'iframe_connected'
# raggruppo per ogni paese gli stream totali per ogni artista
df_grouped = df.groupby(['Country', 'Artist'])['Total Streams (Millions)'].sum().reset_index()
# seleziono l'artista con più stream per ogni paese
top_artists_by_country = df_grouped.sort_values('Total Streams (Millions)', ascending=False)\
.drop_duplicates(subset=['Country'])
# assegno a ogni artista un colore
top_artists_by_country['Top Artist'] = top_artists_by_country['Artist'].astype('category')
# creo la mappa
fig = px.choropleth(
top_artists_by_country,
locations = 'Country', # nomi dei paesi per trovare la posizione sulla mappa
locationmode = 'country names', # specifico il tipo di dato (nomi completi dei paesi)
color = 'Top Artist', # valore da mappare
title = 'Most Streamed Artist by Country', # etichetta/titolo del grafico
color_discrete_sequence = px.colors.qualitative.Dark24 # palette per categorie distinte (valori discreti)
)
fig.show(renderer='notebook')
Conclusioni¶
• Artisti con un maggior numero di stream: BTS, Dua Lipa, Bad Bunny, BLACKPINK
• Paesi con un maggior numero di stream: Svezia, Sud Corea, Sud Africa
• Paesi con un minor numero di stream: Australia, Stati uniti, Regno unito
• Artisti più ascoltati in ogni paese
A quale scopo potrebbe essere utile questa analisi?¶
• marketing: i manager degli artisti possono pianificare campagne pubblicitarie o promozioni di dischi/canzoni dove gli artisti sono più popolari
• tour: i manager possono organizzare concerti nei paesi dove gli artisti sono più popolari o stimare l'audience in base alla popolarità dell'artista in quel paese
• spotify: può adattare i suggerimenti e le playlist in base agli artisti più popolari
• previsioni tendenze: si possono predirre i trend musicali e analizzarne i cambiamenti